﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Configuration;
using System.Data.Linq;
using System.Linq;
using mal.web.Balades.Business.UnitTest.Bootstrap;
using Mal.Balades.AdminBusiness.DataAccess;
using Mal.Balades.AdminBusiness.DataModel;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace mal.web.Balades.Business.UnitTest
{


    /// <summary>
    ///This is a test class for AdminDataAccessTest and is intended
    ///to contain all AdminDataAccessTest Unit Tests
    ///</summary>
    [TestClass()]
    public class AdminDataAccessTest
    {

        private BootstrapManager bootstrapManager;
        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        // 
        //You can use the following additional attributes as you write your tests:
        //
        //Use ClassInitialize to run code before running the first test in the class
        [ClassInitialize()]
        public static void MyClassInitialize(TestContext testContext)
        {
            mal.balades.Business.DataModel.BaladesDataContext.ConnectionStringName = "MalBaladesConnectionString";
            string connexionString = ConfigurationManager.ConnectionStrings[mal.balades.Business.DataModel.BaladesDataContext.ConnectionStringName].ConnectionString.ToLower();
            Assert.IsTrue(connexionString.Contains("unittest"));
        }
        //
        //Use ClassCleanup to run code after all tests in a class have run
        [ClassCleanup()]
        public static void MyClassCleanup()
        {

        }
        //
        //Use TestInitialize to run code before running each test
        [TestInitialize()]
        public void MyTestInitialize()
        {
            bootstrapManager = new BootstrapManager();
            bootstrapManager.InitializeData();
        }
        //
        //Use TestCleanup to run code after each test has run
        //[TestCleanup()]
        //public void MyTestCleanup()
        //{
        //}
        //
        #endregion


        /// <summary>
        ///A test for GetVisit
        ///</summary>
        [TestMethod()]
        public void GetVisitTest()
        {
            AdminDataAccess target = new AdminDataAccess();
            int visitId = 0;
            VisitAdmin actual;

            visitId = 1;
            actual = target.GetVisit(visitId);

            Assert.AreEqual("Visit1", actual.UrlName);
        }

        [TestMethod()]
        public void GetVisitTestUnknownVisit()
        {
            AdminDataAccess target = new AdminDataAccess();
            int visitId = 0;
            VisitAdmin actual;

            visitId = 100;

            try
            {
                actual = target.GetVisit(visitId);
                Assert.Fail("Should throw an ArgumentOutOfRangeException");
            }
            catch (ArgumentOutOfRangeException)
            {

            }

        }

        /// <summary>
        ///A test for GetVisitInformations
        ///</summary>
        [TestMethod()]
        public void GetVisitInformationsTest()
        {
            AdminDataAccess target = new AdminDataAccess();
            ReadOnlyCollection<Information> actual;

            for (int i = 0; i < 10; i++)
            {
                actual = target.GetVisitInformations(i + 1);
                Assert.AreEqual(i + 1, actual.Count);
            }

        }

        /// <summary>
        ///A test for GetVisitPictures
        ///</summary>
        [TestMethod()]
        public void GetVisitPicturesTest()
        {
            AdminDataAccess target = new AdminDataAccess();
            ReadOnlyCollection<Picture> actual;

            for (int i = 0; i < 10; i++)
            {
                actual = target.GetVisitPictures(i + 1);
                Assert.AreEqual(i + 1, actual.Count);
            }
        }

        /// <summary>
        ///A test for GetVisitsForDashboard
        ///</summary>
        [TestMethod()]
        public void GetVisitsForDashboardTest()
        {
            AdminDataAccess target = new AdminDataAccess();
            //ReadOnlyCollection<VisitDashboard> expected = null; 
            ReadOnlyCollection<VisitDashboard> actual;

            actual = target.GetVisitsForDashboard();

            Assert.AreEqual(10, actual.Count);
        }

        /// <summary>
        ///A test for InsertVisit
        ///</summary>
        [TestMethod()]
        [DeploymentItem("mal.balades.AdminBusiness.dll")]
        public void InsertVisitTest()
        {
            AdminDataAccess adminDataAccess = new AdminDataAccess();

            //BaladesAdminDataContext context = null; 
            VisitAdmin visit = null;

            visit = new VisitAdmin();
            using (BaladesAdminDataContext context = adminDataAccess.NewDataContext)
            {
                visit.Latitude = 10;
                visit.Longitude = 11;
                visit.MarketingCategoryID = 1;
                visit.PlaceCategoryID = 2;
                //visit.QualityCategories = true;
                //visit.QualityGps = true;
                //visit.QualityInformations = true;
                //visit.QualityPictures = true;
                //visit.QualitySumUp = true;
                //visit.QualityText = true;
                visit.SumUp = "sumup";
                visit.Text = "text";
                visit.Title = "title";
                visit.UrlName = "visit-test";
                visit.Visible = true;

                adminDataAccess.InsertVisit(context, visit);
            }
            Assert.IsTrue(visit.VisitID.HasValue);
            Assert.AreEqual(VisitBootstrap.NumberOfVisits + 1, visit.VisitID.Value);

            visit = adminDataAccess.GetVisit(visit.VisitID.Value);
            Assert.AreEqual(visit.Latitude, 10);
            Assert.AreEqual(visit.Longitude, 11);
            Assert.AreEqual(visit.MarketingCategoryID, 1);
            Assert.AreEqual(visit.PlaceCategoryID, 2);
            //Assert.AreEqual(visit.QualityCategories, true);
            //Assert.AreEqual(visit.QualityGps, true);
            //Assert.AreEqual(visit.QualityInformations, true);
            //Assert.AreEqual(visit.QualityPictures, true);
            //Assert.AreEqual(visit.QualitySumUp, true);
            //Assert.AreEqual(visit.QualityText, true);
            Assert.AreEqual(visit.SumUp, "sumup");
            Assert.AreEqual(visit.Text, "text");
            Assert.AreEqual(visit.Title, "title");
            Assert.AreEqual(visit.UrlName, "visit-test");
            Assert.AreEqual(visit.Visible, true);

        }

        /// <summary>
        ///A test for SaveVisit
        ///</summary>
        [TestMethod()]
        public void SaveVisitTestCreate()
        {
            AdminDataAccess target = new AdminDataAccess();
            SaveVisitObject visitToSave = null;
            SaveVisitResult expected = null;
            SaveVisitResult actual;
            int informationsNumber = 5;

            visitToSave = new SaveVisitObject();

            List<Information> informations = new List<Information>();
            for (int i = 0; i < informationsNumber; i++)
            {
                informations.Add(new Information() { InformationTypeID = 1, Rank = i, Text = string.Format("info {0}", i) });
            }
            visitToSave.Informations = informations;

            List<Picture> pictures = new List<Picture>();
            for (int i = 0; i < informationsNumber; i++)
            {
                pictures.Add(new Picture()
                {
                    PictureTypeID = 1,
                    Rank = i
                    ,
                    Text = string.Format("picture {0}", i)
                    ,
                    Title = string.Format("title :{0}", i)
                    ,
                    Url = string.Format("url{0}", i)
                });
            }
            visitToSave.Pictures = pictures;

            VisitAdmin visit = new VisitAdmin();

            visit.Latitude = 10;
            visit.Longitude = 11;
            visit.MarketingCategoryID = 1;
            visit.PlaceCategoryID = 2;
            visit.QualityCategories = true;
            visit.QualityGps = true;
            visit.QualityInformations = true;
            visit.QualityPictures = true;
            visit.QualitySumUp = true;
            visit.QualityText = true;
            visit.SumUp = "sumup";
            visit.Text = "text";
            visit.Title = "title";
            visit.UrlName = "visit-test";
            visit.Visible = true;

            visitToSave.Visit = visit;

            actual = target.SaveVisit(visitToSave);

            Assert.AreEqual(VisitBootstrap.NumberOfVisits + 1, actual.VisitID);

            visit = target.GetVisit(actual.VisitID);

            Assert.AreEqual(visit.Latitude, 10);
            Assert.AreEqual(visit.Longitude, 11);
            Assert.AreEqual(visit.MarketingCategoryID, 1);
            Assert.AreEqual(visit.PlaceCategoryID, 2);
            Assert.AreEqual(visit.QualityCategories, true);
            Assert.AreEqual(visit.QualityGps, true);
            Assert.AreEqual(visit.QualityInformations, true);
            Assert.AreEqual(visit.QualityPictures, true);
            Assert.AreEqual(visit.QualitySumUp, true);
            Assert.AreEqual(visit.QualityText, true);
            Assert.AreEqual(visit.SumUp, "sumup");
            Assert.AreEqual(visit.Text, "text");
            Assert.AreEqual(visit.Title, "title");
            Assert.AreEqual(visit.UrlName, "visit-test");
            Assert.AreEqual(visit.Visible, true);

        }

        /// <summary>
        ///A test for SaveVisit
        ///</summary>
        [TestMethod()]
        public void SaveVisitTestUpdate()
        {
            AdminDataAccess target = new AdminDataAccess();
            SaveVisitObject visitToSave = null;
            SaveVisitResult expected = null;
            SaveVisitResult actual;



            actual = target.SaveVisit(visitToSave);
            Assert.AreEqual(expected, actual);
            Assert.Inconclusive("Verify the correctness of this test method.");
        }

        /// <summary>
        ///A test for UpdateInformations
        ///</summary>
        [TestMethod()]
        [DeploymentItem("mal.balades.AdminBusiness.dll")]
        public void UpdateInformationsTest()
        {
            AdminDataAccess target = new AdminDataAccess();
            // BaladesAdminDataContext context = null; 
            VisitAdmin visit = null;
            ReadOnlyCollection<Information> informations = null;
            List<Information> newInformations = null;
            int visitId = 5;

            visit = target.GetVisit(visitId);
            informations = target.GetVisitInformations(visitId);

            newInformations = new List<Information>();
            for (int i = 1; i < visitId; i++)
            {
                newInformations.Add(informations[i]);
            }

            Information info = new Information();
            info.InformationTypeID = 1;
            info.Rank = 10;
            info.Text = "test 1";
            info.VisitID = visitId;
            newInformations.Add(info);

            info = new Information();
            info.InformationTypeID = 1;
            info.Rank = 11;
            info.Text = "test 2";
            info.VisitID = visitId;
            newInformations.Add(info);
            using (BaladesAdminDataContext context = target.NewDataContext)
            {
                target.UpdateInformations(context, visit, newInformations);
            }
            informations = target.GetVisitInformations(visitId);

            Assert.AreEqual(6, informations.Count);

            for (int i = 0; i < 4; i++)
            {
                Assert.AreEqual(string.Format("info {0}-{1}", visitId, i + 2), informations[i].Text);
            }


            Assert.AreEqual("test 1", informations[4].Text);
            Assert.AreEqual("test 2", informations[5].Text);

            for (int i = 0; i < 10; i++)
            {
                if (i != 4)
                {
                    informations = target.GetVisitInformations(i + 1);
                    Assert.AreEqual(i + 1, informations.Count);
                }
            }
        }

        /// <summary>
        ///A test for UpdatePictures
        ///</summary>
        [TestMethod()]
        [DeploymentItem("mal.balades.AdminBusiness.dll")]
        public void UpdatePicturesTest()
        {
            AdminDataAccess target = new AdminDataAccess();
            // BaladesAdminDataContext context = null; 
            VisitAdmin visit = null;
            ReadOnlyCollection<Picture> informations = null;
            List<Picture> newInformations = null;
            int visitId = 5;

            visit = target.GetVisit(visitId);
            informations = target.GetVisitPictures(visitId);

            newInformations = new List<Picture>();
            for (int i = 1; i < visitId; i++)
            {
                newInformations.Add(informations[i]);
            }

            Picture info = new Picture();
            info.PictureTypeID = 1;
            info.Rank = 10;
            info.Text = "test 1";
            info.VisitID = visitId;
            newInformations.Add(info);

            info = new Picture();
            info.PictureTypeID = 1;
            info.Rank = 11;
            info.Text = "test 2";
            info.VisitID = visitId;
            newInformations.Add(info);
            using (BaladesAdminDataContext context = target.NewDataContext)
            {
                target.UpdatePictures(context, visit, newInformations);
            }
            informations = target.GetVisitPictures(visitId);

            Assert.AreEqual(6, informations.Count);

            for (int i = 0; i < 4; i++)
            {
                Assert.AreEqual(string.Format("picture {0}-{1}", visitId, i + 2), informations[i].Text);
            }
            Assert.AreEqual("test 1", informations[4].Text);
            Assert.AreEqual("test 2", informations[5].Text);

            Assert.AreEqual("test 1", informations[4].Text);
            Assert.AreEqual("test 2", informations[5].Text);

            for (int i = 0; i < 10; i++)
            {
                if (i != 4)
                {
                    informations = target.GetVisitPictures(i + 1);
                    Assert.AreEqual(i + 1, informations.Count);
                }
            }
        }

        /// <summary>
        ///A test for UpdateQuality
        ///</summary>
        [TestMethod()]
        [DeploymentItem("mal.balades.AdminBusiness.dll")]
        public void UpdateQualityTest()
        {
            AdminDataAccess target = new AdminDataAccess();
            //BaladesAdminDataContext context = null; 
            VisitAdmin visit = null;
            VisitAdmin visitNew = null;
            int visitId = 5;

            visit = target.GetVisit(visitId);

            visit.QualityCategories = !visit.QualityCategories;
            visit.QualityGps = !visit.QualityGps;
            visit.QualityInformations = !visit.QualityInformations;
            visit.QualityPictures = !visit.QualityPictures;
            visit.QualitySumUp = !visit.QualitySumUp;
            visit.QualityText = !visit.QualityText;
            using (BaladesAdminDataContext context = target.NewDataContext)
            {
                target.UpdateQuality(context, visit);
            }
            visitNew = target.GetVisit(visitId);
            Assert.AreEqual(visit.QualityCategories, visitNew.QualityCategories);
            Assert.AreEqual(visit.QualityGps, visitNew.QualityGps);
            Assert.AreEqual(visit.QualityInformations, visitNew.QualityInformations);
            Assert.AreEqual(visit.QualityPictures, visitNew.QualityPictures);
            Assert.AreEqual(visit.QualitySumUp, visitNew.QualitySumUp);
            Assert.AreEqual(visit.QualityText, visitNew.QualityText);

        }

        /// <summary>
        ///A test for UpdateVisit
        ///</summary>
        [TestMethod()]
        [DeploymentItem("mal.balades.AdminBusiness.dll")]
        public void UpdateVisitTest()
        {
            AdminDataAccess adminDataAccess = new AdminDataAccess();

            //BaladesAdminDataContext context = null; 
            VisitAdmin visit = null;

            visit = adminDataAccess.GetVisit(1);
            using (BaladesAdminDataContext context = adminDataAccess.NewDataContext)
            {

                visit.Latitude = 10;
                visit.Longitude = 11;
                visit.MarketingCategoryID = 1;
                visit.PlaceCategoryID = 2;
                //visit.QualityCategories = true;
                //visit.QualityGps = true;
                //visit.QualityInformations = true;
                //visit.QualityPictures = true;
                //visit.QualitySumUp = true;
                //visit.QualityText = true;
                visit.SumUp = "sumup";
                visit.Text = "text";
                visit.Title = "title";
                visit.UrlName = "visit-test";
                visit.Visible = true;

                adminDataAccess.UpdateVisit(context, visit);
            }

            visit = adminDataAccess.GetVisit(visit.VisitID.Value);
            Assert.AreEqual(visit.Latitude, 10);
            Assert.AreEqual(visit.Longitude, 11);
            Assert.AreEqual(visit.MarketingCategoryID, 1);
            Assert.AreEqual(visit.PlaceCategoryID, 2);
            //Assert.AreEqual(visit.QualityCategories, true);
            //Assert.AreEqual(visit.QualityGps, true);
            //Assert.AreEqual(visit.QualityInformations, true);
            //Assert.AreEqual(visit.QualityPictures, true);
            //Assert.AreEqual(visit.QualitySumUp, true);
            //Assert.AreEqual(visit.QualityText, true);
            Assert.AreEqual(visit.SumUp, "sumup");
            Assert.AreEqual(visit.Text, "text");
            Assert.AreEqual(visit.Title, "title");
            Assert.AreEqual(visit.UrlName, "visit-test");
            Assert.AreEqual(visit.Visible, true);
        }


        /// <summary>
        ///A test for UpdateFeedItem
        ///</summary>
        [TestMethod()]
        public void UpdateFeedItemsTest()
        {
            AdminDataAccess adminDataAccess = new AdminDataAccess();

            //target.UpdateFeedItem(feed);
            int feedId1;
            int feedId2;
            Feed feed1;
            Feed feed2;
            DateTime date1 = new DateTime(2010, 1, 1);
            DateTime date2 = new DateTime(2011, 1, 1);

            using (BaladesAdminDataContext context = adminDataAccess.NewDataContext)
            {
                List<Feed> feeds = context.Feeds.ToList();

                feed1 = feeds[0];
                feeds[0].LastUpdate = date1;

                if (context.FeedItems.Count() > 0)
                {
                    context.FeedItems.DeleteAllOnSubmit(context.FeedItems);
                }

                feedId1 = feeds[0].FeedId;

                for (int i = 0; i < 3; i++)
                {
                    FeedItem feedItem = new FeedItem();
                    feedItem.Feed = feeds[0];
                    feedItem.Title = string.Format("Feed {0}-{1}", feedId1, i);

                    context.FeedItems.InsertOnSubmit(feedItem);
                }

                feedId2 = feeds[1].FeedId;
                feeds[1].LastUpdate = date2;

                for (int i = 0; i < 4; i++)
                {
                    FeedItem feedItem = new FeedItem();
                    feedItem.Feed = feeds[1];
                    feedItem.Title = string.Format("Feed {0}-{1}", feedId2, i);

                    context.FeedItems.InsertOnSubmit(feedItem);
                }

                context.SubmitChanges();
            }

            adminDataAccess.UpdateFeedItems(feed1.FeedId);

            using (BaladesAdminDataContext context = adminDataAccess.NewDataContext)
            {
                DataLoadOptions loadOptions = new DataLoadOptions();
                loadOptions.LoadWith<Feed>(v => v.FeedItems);

                context.LoadOptions = loadOptions;

                feed2 = context.Feeds.First(f => f.FeedId == feedId1);

                Assert.IsTrue( feed2.LastUpdate.Value>DateTime.Now.AddSeconds(-10));
                Assert.AreEqual(5, feed2.FeedItems.Count);

                for (int i = 0; i < 3; i++)
                {
                    Assert.AreNotEqual(string.Format("Feed {0}-{1}", feedId1, i), feed2.FeedItems[i].Title);
                }

                feed2 = context.Feeds.First(f => f.FeedId == feedId2);

                Assert.AreEqual(4, feed2.FeedItems.Count);
                Assert.AreEqual( date2,feed2.LastUpdate.Value);
                for (int i = 0; i < 4; i++)
                {
                    Assert.AreEqual(string.Format("Feed {0}-{1}", feedId2, i), feed2.FeedItems[i].Title);
                }
            }
        }
    }
}
